#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
配置管理器
负责管理系统配置的读取、保存、验证等功能
"""

import os
import json
import logging
from typing import Dict, Any, Optional
from pathlib import Path


class ConfigManager:
    """配置管理器"""

    def __init__(self, config_file: str = "config.json"):
        self.config_file = config_file
        self.logger = logging.getLogger(__name__)

        # 默认配置
        self.default_config = {
            "output_path": "E:/video/",
            "oss": {
                "access_key_id": "",
                "access_key_secret": "",
                "bucket_name": "",
                "endpoint": "oss-cn-hangzhou.aliyuncs.com",
                "enabled": False
            },
            "service": {
                "host": "0.0.0.0",
                "port": 5000,
                "auto_start": False
            },
            "ui": {
                "theme": "default",
                "log_level": "INFO",
                "auto_save": True
            },
            "worker": {
                "enabled": False,
                "id": "worker_001",
                "workerName": "Windows-Python-Worker",
                "ipAddress": "192.168.1.100",
                "hostname": "YOUR-PC-NAME",
                "maxConcurrentTasks": 4,
                "capabilities": ["VIDEO_RENDER", "IMAGE_PROCESS"],
                "version": "1.0.0",
                "api_base": "http://your-backend-server:8080/api/job-worker",
                "heartbeat_interval": 30,
                "task_poll_interval": 10,
                "max_retries": 3,
                "connect_timeout": 30,
                "retry_delay": 5
            }
        }

        # 当前配置
        self.config = self.default_config.copy()

        # 加载配置
        self.load_config()

    def load_config(self) -> bool:
        """加载配置文件"""
        try:
            if os.path.exists(self.config_file):
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    loaded_config = json.load(f)

                # 合并配置，保持默认值
                self.config = self._merge_config(self.default_config, loaded_config)
                self.logger.info(f"配置文件加载成功: {self.config_file}")
                return True
            else:
                self.logger.info("配置文件不存在，使用默认配置")
                self.save_config()  # 创建默认配置文件
                return True

        except Exception as e:
            self.logger.error(f"加载配置文件失败: {e}")
            self.config = self.default_config.copy()
            return False

    def save_config(self) -> bool:
        """保存配置文件"""
        try:
            # 确保目录存在
            config_dir = os.path.dirname(os.path.abspath(self.config_file))
            if config_dir:
                os.makedirs(config_dir, exist_ok=True)

            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, indent=2, ensure_ascii=False)

            self.logger.info(f"配置文件保存成功: {self.config_file}")
            return True

        except Exception as e:
            self.logger.error(f"保存配置文件失败: {e}")
            return False

    def _merge_config(self, default: Dict[str, Any], loaded: Dict[str, Any]) -> Dict[str, Any]:
        """合并配置，保持默认配置的结构"""
        result = default.copy()

        for key, value in loaded.items():
            if key in result:
                if isinstance(value, dict) and isinstance(result[key], dict):
                    result[key] = self._merge_config(result[key], value)
                else:
                    result[key] = value

        return result

    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值，支持点号分隔的路径"""
        try:
            keys = key.split('.')
            value = self.config

            for k in keys:
                if isinstance(value, dict) and k in value:
                    value = value[k]
                else:
                    return default

            return value

        except Exception:
            return default

    def set(self, key: str, value: Any) -> bool:
        """设置配置值，支持点号分隔的路径"""
        try:
            keys = key.split('.')
            config = self.config

            # 导航到最后一级的父级
            for k in keys[:-1]:
                if k not in config:
                    config[k] = {}
                config = config[k]

            # 设置值
            config[keys[-1]] = value
            return True

        except Exception as e:
            self.logger.error(f"设置配置值失败: {key} = {value}, {e}")
            return False

    def get_output_path(self) -> str:
        """获取输出路径"""
        return self.get('output_path', 'E:/video/')

    def set_output_path(self, path: str) -> bool:
        """设置输出路径"""
        if path and isinstance(path, str):
            # 确保路径以斜杠结尾
            if not path.endswith('/') and not path.endswith('\\'):
                path += '/'
            return self.set('output_path', path)
        return False

    def get_oss_config(self) -> Dict[str, Any]:
        """获取OSS配置"""
        return self.get('oss', {})

    def set_oss_config(self, oss_config: Dict[str, Any]) -> bool:
        """设置OSS配置"""
        if isinstance(oss_config, dict):
            current_oss = self.get('oss', {})
            current_oss.update(oss_config)
            return self.set('oss', current_oss)
        return False

    def get_service_config(self) -> Dict[str, Any]:
        """获取服务配置"""
        return self.get('service', {})

    def set_service_config(self, service_config: Dict[str, Any]) -> bool:
        """设置服务配置"""
        if isinstance(service_config, dict):
            current_service = self.get('service', {})
            current_service.update(service_config)
            return self.set('service', current_service)
        return False

    def get_worker_config(self) -> Dict[str, Any]:
        """获取Worker配置"""
        return self.get('worker', {})

    def set_worker_config(self, worker_config: Dict[str, Any]) -> bool:
        """设置Worker配置"""
        if isinstance(worker_config, dict):
            current_worker = self.get('worker', {})
            current_worker.update(worker_config)
            return self.set('worker', current_worker)
        return False

    def is_worker_enabled(self) -> bool:
        """检查Worker是否启用"""
        return self.get('worker.enabled', False)

    def enable_worker(self, enabled: bool = True) -> bool:
        """启用或禁用Worker"""
        return self.set('worker.enabled', enabled)

    def validate_config(self) -> Dict[str, bool]:
        """验证配置的有效性"""
        validation_result = {
            'output_path': self._validate_output_path(),
            'oss': self._validate_oss_config(),
            'service': self._validate_service_config(),
            'worker': self._validate_worker_config()
        }

        return validation_result

    def _validate_output_path(self) -> bool:
        """验证输出路径"""
        try:
            output_path = self.get_output_path()
            if not output_path:
                return False

            # 尝试创建目录（如果不存在）
            Path(output_path).mkdir(parents=True, exist_ok=True)

            # 检查是否可写
            test_file = os.path.join(output_path, '.test_write')
            try:
                with open(test_file, 'w') as f:
                    f.write('test')
                os.remove(test_file)
                return True
            except:
                return False

        except Exception:
            return False

    def _validate_oss_config(self) -> bool:
        """验证OSS配置"""
        try:
            oss_config = self.get_oss_config()

            # 如果未启用OSS，跳过验证
            if not oss_config.get('enabled', False):
                return True

            # 检查必需的配置项
            required_fields = ['access_key_id', 'access_key_secret', 'bucket_name', 'endpoint']
            for field in required_fields:
                if not oss_config.get(field):
                    return False

            return True

        except Exception:
            return False

    def _validate_service_config(self) -> bool:
        """验证服务配置"""
        try:
            service_config = self.get_service_config()

            # 检查端口号
            port = service_config.get('port', 5000)
            if not isinstance(port, int) or port < 1 or port > 65535:
                return False

            # 检查主机地址
            host = service_config.get('host', '0.0.0.0')
            if not isinstance(host, str) or not host:
                return False

            return True

        except Exception:
            return False

    def _validate_worker_config(self) -> bool:
        """验证Worker配置"""
        try:
            worker_config = self.get_worker_config()

            # 如果未启用Worker，跳过验证
            if not worker_config.get('enabled', False):
                return True

            # 检查必需的配置项
            required_fields = ['id', 'workerName', 'api_base']
            for field in required_fields:
                if not worker_config.get(field):
                    return False

            # 检查数值配置
            max_concurrent = worker_config.get('maxConcurrentTasks', 4)
            if not isinstance(max_concurrent, int) or max_concurrent < 1:
                return False

            heartbeat_interval = worker_config.get('heartbeat_interval', 30)
            if not isinstance(heartbeat_interval, int) or heartbeat_interval < 10:
                return False

            task_poll_interval = worker_config.get('task_poll_interval', 10)
            if not isinstance(task_poll_interval, int) or task_poll_interval < 5:
                return False

            # 检查API地址格式
            api_base = worker_config.get('api_base', '')
            if not api_base.startswith(('http://', 'https://')):
                return False

            # 检查capabilities是否为列表
            capabilities = worker_config.get('capabilities', [])
            if not isinstance(capabilities, list):
                return False

            return True

        except Exception:
            return False

    def reset_to_default(self) -> bool:
        """重置为默认配置"""
        try:
            self.config = self.default_config.copy()
            return self.save_config()
        except Exception as e:
            self.logger.error(f"重置配置失败: {e}")
            return False

    def backup_config(self, backup_file: Optional[str] = None) -> bool:
        """备份当前配置"""
        try:
            if backup_file is None:
                from datetime import datetime
                timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
                backup_file = f"config_backup_{timestamp}.json"

            with open(backup_file, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, indent=2, ensure_ascii=False)

            self.logger.info(f"配置备份成功: {backup_file}")
            return True

        except Exception as e:
            self.logger.error(f"配置备份失败: {e}")
            return False

    def get_all_config(self) -> Dict[str, Any]:
        """获取完整配置"""
        return self.config.copy()

    def update_config(self, new_config: Dict[str, Any]) -> bool:
        """更新配置"""
        try:
            self.config = self._merge_config(self.config, new_config)
            return True
        except Exception as e:
            self.logger.error(f"更新配置失败: {e}")
            return False


# 全局配置管理器实例
config_manager = ConfigManager()


def get_config() -> ConfigManager:
    """获取全局配置管理器实例"""
    return config_manager


if __name__ == "__main__":
    # 测试配置管理器
    logging.basicConfig(level=logging.INFO)

    cm = ConfigManager()

    print("当前配置:")
    print(json.dumps(cm.get_all_config(), indent=2, ensure_ascii=False))

    print("\n验证结果:")
    validation = cm.validate_config()
    for key, is_valid in validation.items():
        print(f"  {key}: {'✅ 有效' if is_valid else '❌ 无效'}")

    # 测试设置和获取
    cm.set_output_path("D:/test/")
    print(f"\n输出路径: {cm.get_output_path()}")

    cm.save_config()
    print("配置已保存")